package com.liang.Event.Listener;

import com.liang.Event.Events.ExcusePassEvent;
import com.liang.Event.Events.ExcuseUnPassEvent;
import com.liang.Event.Events.NoticePublishEvent;
import com.liang.Event.Events.receiveNoticeEvent;
import com.liang.mapper.ArmyalluserzDAO;
import com.liang.mapper.ArmyxDAO;
import com.liang.mapper.UserandnoticeDAO;
import com.liang.myWebSocketServer.WebSocketServer;
import com.liang.pojo.dto.ExcuseDto;
import com.liang.pojo.userandnotice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;


@Repository
public class MyListener {

    /**
     * 存储redis中的notice需要接收的人员的key前缀
     */
    @Value("notice")
    private String noticeTitle;

    @Value("timer_notice")
    private String timer_notice;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Resource
    UserandnoticeDAO userandnoticeDAO;

    @Resource
    ArmyxDAO armyxDAO;

    @Autowired
    WebSocketServer webSocketServer;
    /**
     * 处理noticePublish的相关redis中的操作。
     * @param noticePublishEvent
     */
    //存储需要接收notice信息的人员id到redis中，并且添加到userandnotice中。
    @EventListener
    @Async
    public void NoticePublishListener(NoticePublishEvent noticePublishEvent){

        //获取当前发布的通知的id
        Long Noticeid = noticePublishEvent.getNoticeid();

        //和发布人员的id
        Long userId = noticePublishEvent.getUserId();

        //获取师下面的所有成员的id
        List<Long> allUser = armyxDAO.getAllUser();

        //将查到的数据存入数据库userandnotice中和添加到redis中。
        allUser.stream().forEach((item)->{
            userandnotice userandnotice = new userandnotice();
            userandnotice.setUser_id(item);
            userandnotice.setNotice_id(Noticeid);
            userandnotice.setNotice_status(false);
            userandnoticeDAO.insert(userandnotice);
            //存入redis中
            redisTemplate.opsForSet().add(noticeTitle+Noticeid,item.toString());
        });

        //将这个notice的id加入定时器的redis中，以便定时器定时的通知用户对消息的接收。
        redisTemplate.opsForSet().add(timer_notice,Noticeid.toString());
    }


    @EventListener
    @Async
    public  void  receiveNoticeListener(receiveNoticeEvent receiveNoticeEvent){

        userandnotice userandnotice = receiveNoticeEvent.getUserandnotice();

        //从redis中移除这个noticeid，代表着他已经被接收了
        redisTemplate.opsForSet().remove(noticeTitle+userandnotice.getNotice_id(),userandnotice.getUser_id().toString());

        //从用户未接受的rediset中移除这个消息的消息id。
        //判断这个消息是否被该接收的人全部接收
        Set<String> members = redisTemplate.opsForSet().members(noticeTitle + userandnotice.getNotice_id());
        //被完全接收则在timer_notice中移除这个noticeid。
        if(members.size() == 0) {
            redisTemplate.opsForSet().remove(timer_notice, userandnotice.getNotice_id().toString());
        }
    }


    //用户请假申请被批准
    @EventListener
    @Async
    public void excusePassEventListener(ExcusePassEvent excusePassEvent){
        ExcuseDto excuseDto = excusePassEvent.getExcuseDto();
        webSocketServer.sendOneMessage(excuseDto.getUser_id(),"你于"+excuseDto.getCreate_time()+"申请的假条被批准");
    }

    /**
     * 用户请假申请未批准
     */
    @EventListener
    @Async
    public void excuseUnPassEventListener(ExcuseUnPassEvent excuseUnPassEvent){
        ExcuseDto excuseDto = excuseUnPassEvent.getExcuseDto();
        webSocketServer.sendOneMessage(excuseDto.getUser_id(),"你于"+excuseDto.getCreate_time()+"申请的假条未被批准");
    }
}
